import bpy
from uuid import uuid4
from bpy.types import Context
from ...addon.naming import FluidLabNaming
from bpy.props import EnumProperty, StringProperty
from ...libs.functions.get_common_vars import get_common_vars
from ...libs.functions.collections import set_active_collection_by_name
from ...libs.functions.object import name_with_zfill, set_active_object
from .base_class_forces_add import FLUIDLAB_OT_fluid_forces_add_base_class
from ..forces.ops_settings.common_methods import reset_properties_to_defaults

invalid_obs_sel = "Not valid object are selected!"


class FLUIDLAB_OT_fluid_force_list_add(FLUIDLAB_OT_fluid_forces_add_base_class):
    bl_idname = "fluidlab.fluid_force_list_add"
    bl_label = "Add New Force Group"
    bl_description = "Add Force Group to List"
    bl_options = {"REGISTER", "UNDO"}

    type_of_force: EnumProperty(
        name="Type of Force",
        description="The type of force you want to use", 
        items=[
            ('GENERATED',   "Generated",    "", 0),
            ('CUSTOM',      "Custom",       "", 1),
        ],
        default='GENERATED'
    )

    force_name: StringProperty(
        name="Force Name",
        description="The name of the new Force",
        default=""
    )


    def get_force_ob_name(self, context:Context, with_zfill:bool=False) -> str:

        # Sugiero el nuevo nombre:
        fluid_forces_groups = get_common_vars(context, get_fluid_forces_groups=True)
        ff_active_group = fluid_forces_groups.active
        forces_list = ff_active_group.forces
        active_force = forces_list.active
        
        if forces_list.is_void:
            return FluidLabNaming.FORCE_OB_01
        
        force_ob = active_force.force

        if with_zfill:
            place = ff_active_group.group_coll.objects
            new_name = name_with_zfill(context, force_ob.name, place)
        else:
            new_name = force_ob.name

        return new_name


    def invoke(self, context, event):
        # Sugiero el nombre:
        self.force_name = self.get_force_ob_name(context, with_zfill=True)
        return context.window_manager.invoke_props_dialog(self, width=280)
        

    def draw(self, context):

        layout = self.layout
        layout.use_property_decorate = False
        layout.use_property_split = False

        main_col = layout.column(align=True)

        type_force = main_col.row(align=True)
        type_force.scale_y = 1.3
        type_force.prop(self, "type_of_force", expand=True)

        main_col.separator()

        if self.type_of_force == 'GENERATED':
            f_name = main_col.row(align=True)
            if len(self.force_name) <= 0:
                f_name.alert = True
            f_name.prop(self, "force_name", text="Name")
        else:
            # Si no hay objetos seleccionados doy feedbak:
            feedback = main_col.box()
            if len(context.selected_objects) <= 0:
                feedback.alert = True
                feedback.label(text=invalid_obs_sel, icon='ERROR')
            else:
                feedback.label(text=f"Convert {context.active_object.name} object in force", icon='INFO')
    

    def execute(self, context):

        # Si estamos en tipo custom y no hay objetos seleccionados doy feedbak y cancelamos:
        if self.type_of_force == 'CUSTOM':
            if len(context.selected_objects) <= 0:
                self.report({'ERROR'}, invalid_obs_sel)
                return {'CANCELLED'}

        scn, fluid_forces_groups = get_common_vars(context, get_scn=True, get_fluid_forces_groups=True)
        ff_group_active = fluid_forces_groups.active

        if not ff_group_active:
            return {'CANCELLED'}
        
        self.create_forces_main_coll_if_not_exit(context)

        cursor3D = context.scene.cursor
        place = context.view_layer.objects
        force_name = name_with_zfill(context, FluidLabNaming.FORCE_OB_01, place)
        force_coll = ff_group_active.group_coll
        forces_list = ff_group_active.forces
        id_name = str(uuid4())
        set_active_collection_by_name(context, force_coll.name)

        if self.type_of_force == 'GENERATED':
            bpy.ops.object.select_all(action='DESELECT')
            bpy.ops.object.effector_add(type='TURBULENCE', enter_editmode=False, align='WORLD', location=cursor3D.location, scale=(1, 1, 1))
        
        force = context.active_object
        if force:

            if self.type_of_force == 'CUSTOM':
                if force.field is None:
                    bpy.ops.object.forcefield_toggle()
                    
                # deslinko de donde este:
                [coll.objects.unlink(force) for coll in force.users_collection if coll.name != 'RigidBodyWorld']
                        
                # lo linco a su collection:
                force_coll.objects.link(force)

                field = force.field
                field.type = 'TURBULENCE'
                # les reseteamos las properties:
                reset_properties_to_defaults(field)

            force.name = force_name

            if FluidLabNaming.FORCE_OB not in force:
                force[FluidLabNaming.FORCE_OB] = True

            forces_list.add_item(item_id=id_name, label_txt=force_name, force_ob=force, force_type=self.type_of_force)

            bpy.ops.object.select_all(action='DESELECT')
            set_active_object(context, force)
            force.select_set(True)

        return {'FINISHED'}

    
            

        
